import { useState, useEffect } from 'react';

/**
 * 自定义Hook: useLocalStorage
 * 
 * 这个Hook用于在localStorage中存储和检索数据，并在数据变化时自动更新localStorage
 * 
 * @param {string} key - localStorage中存储数据的键名
 * @param {any} initialValue - 初始值，当localStorage中没有对应数据时使用
 * @returns {Array} - 返回当前存储的值和更新该值的函数，类似于useState
 * 
 * 使用示例:
 * const [name, setName] = useLocalStorage('name', 'Guest');
 * // 现在name将从localStorage中读取，如果不存在则为'Guest'
 * // 调用setName会更新状态并将新值保存到localStorage
 */
function useLocalStorage(key, initialValue) {
  // 创建状态来存储值
  // 惰性初始化状态，只在组件首次渲染时执行
  const [storedValue, setStoredValue] = useState(() => {
    try {
      // 尝试从localStorage获取值
      const item = window.localStorage.getItem(key);
      // 如果找到了值，解析并返回它
      // 否则返回初始值
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // 如果出错（例如localStorage不可用），返回初始值
      console.error(`Error reading localStorage key "${key}":`, error);
      return initialValue;
    }
  });

  // 创建一个函数来更新localStorage和状态
  const setValue = (value) => {
    try {
      // 允许值是一个函数，就像useState的setter一样
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      
      // 保存到状态
      setStoredValue(valueToStore);
      
      // 保存到localStorage
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      // 处理错误情况
      console.error(`Error setting localStorage key "${key}":`, error);
    }
  };

  // 监听其他窗口/标签页的storage事件
  useEffect(() => {
    const handleStorageChange = (event) => {
      if (event.key === key) {
        try {
          setStoredValue(event.newValue ? JSON.parse(event.newValue) : initialValue);
        } catch (error) {
          console.error(`Error parsing localStorage value:`, error);
        }
      }
    };

    // 添加事件监听器
    window.addEventListener('storage', handleStorageChange);
    
    // 清理函数
    return () => {
      window.removeEventListener('storage', handleStorageChange);
    };
  }, [key, initialValue]);

  return [storedValue, setValue];
}

export default useLocalStorage;